"""
有一些网站为了避免爬虫的恶意访问，会设置一些反爬虫机制，常见的饭爬虫机制主要有：
  1、通过分析用户请求的Headers信息进行反爬虫
  2、通过检测用户行为进行反爬虫，比如通过判断同一个IP在短时间内是否频繁访问对应网站等进行分析
  3、通过动态页面增加爬虫的爬取难度，达到反爬虫的目的

  第一种反爬虫机制在目前网站中应用的最多，大部分反爬虫网站会对用户请求的Headers信息的“User-Agent”字段进行检测来判断身份，有时，这类反爬虫的网站还会对“Referer”字段进行检测。我们可以在爬虫中构造这些用户请求的Headers信息，以此将爬虫伪装成浏览器，简单的伪装只需设置好“User-Agent”字段的信息即可，如果要进行高相似度的路蓝旗伪装，则需要将用户请求的Headers信息中常见的字段都在爬虫中设置好
  第二种反爬虫机制的网站，可以通过之前学习的使用代理服务器并经常切换代理服务器的方式，一般就能够攻克限制
  注意：！！！第三种反爬虫机制的网站，可以利用一些工具软件，比如selenium+phantomJS，就可以攻克限制！！！

"""



#1.使用代理服务器

import urllib.request
import http.cookiejar

url = "http://news.163.com/18/0306/09/DC71LRR20001875N.html"

# 以字典的形式设置headers，格式是[(字段名，字段值),(字段名，字段值)]，这里先用字典，在下面会用for把它转为列表元组的形式
headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    #'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',

    #"Accept-Encoding": "gzip, deflate"（错）
    #要么干脆不写，要写就写:    "Accept-Encoding": "gb2312,utf-8",

    "Accept-Language": "zh-CN,zh;q=0.9",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
    "Connection": "keep-alive",
    "referer": "http://www.163.com" #refer字段的值一般可以设置为要爬取的网页的域名地址或对应网站的主页网址
}

#设置cookie
cjar = http.cookiejar.CookieJar()
proxy = urllib.request.ProxyHandler({'http': "127.0.0.1:8888"}) #在实际项目中，不一定要将Fiddler设置为代理服务器来伪装成浏览器，这里设置代理服务器是为了方便Fiddler抓包，方便测试。实际可以这里可以省去
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler, urllib.request.HTTPCookieProcessor(cjar))
#代理服务器去掉之后应该写为:opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar))

# 建立空列表，为了以指定格式存储头信息
headall = []
for key,value in headers.items():   #循环字典h，每次循环提取一个键值对
    item = (key, value) #把提取到的键值对，做成元组赋予item
    headall.append(item)    #添加到列表中

opener.addheaders = headall # 将指定格式的headers信息添加好
urllib.request.install_opener(opener)   # 将opener安装为全局

data = urllib.request.urlopen(url).read()
# data = data.decode("utf-8")
fhandle = open("D://testweb/part6/1.html", "wb")
fhandle.write(data)
fhandle.close()


"""
需要注意的几点：

1）代码里没有设置Accept-Encoding字段，如果设置为gzip或deflate就可能报错，此时改成utf-8或gb2312就好了，或者干脆不设置这个字段信息，因为入设置了压缩编码，那么请求的数据就是压缩数据包需要解压才行，但这是伪装的浏览器没有解压功能的程序，所以就不用多此一举

2）用Fiddler做代理服务器爬取网页时，网址要以具体文件名或者‘/’结尾,例如：
url = "http://news.163.com/"
    有具体文件，写具体文件的地址就可以了，例如：
url = "http://news.163.com/18/0306/09/DC71LRR20001875N.html"

3）referer字段一般设置为要爬取网页的域名地址或对应网站的主页
"""
